const crypto = require("crypto");
const jwt = require('jsonwebtoken'); //webtoken
const cookieParser = require("cookie-parser")();


const ltt = `${APP.localProperty.login_token_time}m`;
const ctt = `${APP.localProperty.code_token_time}m`;
const att = `${APP.localProperty.access_token_time}m`;
const ltt_cookie = APP.localProperty.login_token_time * 60 * 1000;

/**加密算法*/
function encryption(pwd) {
    var encoder = crypto.createHash('sha256'); //md5, sha1, sha256
    return encoder.update(pwd).digest('base64');
}

function enPasswd(pwd) {
    return encryption(pwd + APP.public_salt).toLowerCase();
}
/**
 * 客户端加密密码的样例
 * @param pwd 原始密码
 * @param code 服务器公共盐
 * @param salt 本次随机盐(时间戳+"."+任意值)
 * */
function summoner(pwd, code, salt) {
    if (!salt) salt = Date.now();
    pwd = encryption(encryption(pwd + code).toLowerCase() + salt).toLowerCase();
    return { pwd: pwd, salt: salt }
}
/**
 * 登录时间戳验证阈值
 * */
const threshold = APP.localProperty.AUTH_TIME_THRESHOLD;
const cookieKey = APP.localProperty.cookie_prefix + 'login-token';

/**
 * 验证登录
 * @param clientPwd 客户端密码(二次加密后)
 * @param clientSalt 客户端随机盐
 * @param serverPwd 服务器保存的密码(一次加密后)
 * @param time 接收时间
 * @return 0 成功登录
 * @return 1 密码错误
 * @return 2 随机盐格式有误
 * @return 3 随机盐失效
 * */
function auth(clientPwd, clientSalt, serverPwd, time) {
    let i = clientSalt.indexOf('.');
    if (i < 0 || isNaN(i = clientSalt.substring(0, i))) return 2;
    if (Math.abs(time - parseInt(i)) > threshold) return 3;
    serverPwd = encryption(serverPwd + clientSalt).toLowerCase();
    return serverPwd === clientPwd ? 0 : 1;
}
/**
 * 生成token
 * @param time 访问时间
 * @param u 用户
 * @param res express的res
 * */
function setToken(time, u, res) {
    let token = "";
    if (u) token = jwt.sign({ u: u }, APP.token_private, {
        expiresIn: ltt // 设置过期时间
    });



    res.cookie(cookieKey, token, { expires: new Date(time + ltt_cookie) });
}
/**
 * 验证用户
 * @param force 强制验证
 * */
function middle_checker(force) {
    return (req, res, next) => {
        if (req.user) return next();
        cookieParser(req, res, () => {
            let token = req.cookies[cookieKey];
            if (!token) return next();
            jwt.verify(token, APP.token_private, async (err, result) => {
                if (err) {
                    if (force) return res.status(403).json({ success: false, err: "无效登录" }).end();
                } else req.user = result.u;
                next();
            });
        });
    };
}
/**
 * 获取用户
 * @param req express的req
 * @param res express的res
 * @return 令牌类型/已经设置的用户
 * @return req.user 用户
 * */
async function getUser(req, res) {
    return new Promise(r => middle_checker(false)(req, res, r));
}
module.exports = {
    auth: auth,
    setToken: setToken,
    middle_checker: middle_checker,
    getUser: getUser,
    enPasswd: enPasswd
}